using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using QuickLaunch.Properties;
using System.Runtime.InteropServices;

namespace QuickLaunch
{
    public partial class SearchBoxForm : Form
    {
        public SearchBoxForm()
        {
            InitializeComponent();

            // initialize the region of the form.
            BitmapRegion.CreateControlRegion(this, Resources.BgImag);

            // register the form in the form manager.
            Program.formManager.AddForm(this);
        }

        private void SearchBoxForm_Load(object sender, EventArgs e)
        {
            // initialize the autocomplete form
            this.InitializeAutocompleteForm();
        }

        #region Auto-complete form

        private AutoCompleteForm autoComplete = null;

        private void InitializeAutocompleteForm()
        {
            this.autoComplete = new AutoCompleteForm(this);
            this.autoComplete.Location = new Point(this.Location.X + 4, this.Location.Y + 66);
        }

        #endregion

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            this.ActivateSearchBox();
        }

        private void toolStripMenuItem_Search_Click(object sender, EventArgs e)
        {
            this.ActivateSearchBox();
        }

        #region Activation and Deactivation

        #region Public Methods

        public void ActivateSearchBox()
        {
            this.Visible = true;

            if (!string.IsNullOrEmpty(this.tb_Search.Text))
                this.autoComplete.Visible = true;

            this.Activate();
            // set as foreground window,
            // sometimes, the setforegroundwindow returns false randomly, 
            // so I use a loop to try again.
            WinAPI.SetForegroundWindow(this.Handle);
            this.tb_Search.Focus();
            this.tb_Search.SelectAll();
        }

        public void DeactivateSearchBox()
        {
            this.Visible = false;
            this.autoComplete.Visible = false;
        }

        #endregion

        #endregion

        #region Close Forms

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            if (!e.Cancel)
                this.autoComplete.Close();
        }

        private void btn_Close_Click(object sender, EventArgs e)
        {
            this.DeactivateSearchBox();
        }

        private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
        {
            this.Close(); // exit the program
        }

        #endregion

        private void tb_Search_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (!string.IsNullOrEmpty(this.tb_Search.Text))
                {
                    // open the item with Shell operation.
                    string fileName = this.autoComplete.GetSelectedItem();
                    this.DeactivateSearchBox();

                    // execute the command:
                    bool opened = false;
                    if (!string.IsNullOrEmpty(fileName))
                        // check the parameter
                        opened = Program.fileNameSearch.HitFile(fileName, GetParameter());
                    else
                        // open the cmd with shell
                        opened = Shell.Open(this.tb_Search.Text.Replace('/', ' '));

                    //if (!opened)
                    //    MessageBox.Show(Resources.Msg_CannotOpenFile);
                }
            }
            else if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
            {
                // choose items in the list.
                if (this.autoComplete.Visible)
                {
                    this.autoComplete.SelectItem(e.KeyCode == Keys.Down ? 1 : -1);
                }
                e.Handled = true;
            }
        }

        private void tb_Search_TabPressed(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(GetParameter()))
                return; // if contain parameter, do nothing

            string item = this.autoComplete.GetSelectedItem();
            if (!string.IsNullOrEmpty(item))
            {
                this.tb_Search.Text = FileNameHelper.GetFileName(item);
                this.tb_Search.SelectionStart = this.tb_Search.Text.Length;
            }
        }

        private void btn_Setting_Click(object sender, EventArgs e)
        {
            SettingForm settings = new SettingForm();
            settings.Show();
        }

        private void tb_Search_TextChanged(object sender, EventArgs e)
        {
            // check to see if the textbox is empty at the moment.
            if (string.IsNullOrEmpty(this.tb_Search.Text))
            {
                // make the autocomplete invisible
                this.autoComplete.Visible = false;
            }
            else if (!HasParameter())
            {
                // set the autocomplete's property and build/show the autocomplete list
                this.autoComplete.ListItems(this.tb_Search.Text.Trim());

                // if the current mouse pointer is inside the autocomplete list form, 
                // move the mouse to the top left corner of search textbox.
                // so that the mouse will not interfere with the search result selection.
                if (this.autoComplete.Bounds.Contains(WinAPI.GetCursorPos()))
                {
                    Rectangle winRect = this.RectangleToScreen(this.ClientRectangle);
                    WinAPI.SetCursorPos(winRect.Location.X, winRect.Location.Y);
                }

                this.tb_Search.Focus();
            }
            // else if contain paramerter, no search
        }

        private void toolStripMenuItem_About_Click(object sender, EventArgs e)
        {
            About aboutForm = new About();
            aboutForm.ShowDialog();
        }

        private bool HasParameter()
        {
            return this.tb_Search.Text.Contains(" /");
        }
        /// <summary>
        /// determine if the cmd text contains parameters
        /// </summary>
        private string GetParameter()
        {
            int index = this.tb_Search.Text.IndexOf(" /");
            if (index < 0 || index >= this.tb_Search.Text.Length - 2)
                return ""; // no parameter
            // substring the parameter part
            return this.tb_Search.Text.Substring(index + 2).Trim();
        }
    }
}